/**
 * 拓扑渲染器
 * 依赖svg_lin.js，topology.js
 */

// 拓扑渲染器
class TopologyRenderer{
  constructor(container,topology,nodeInnerHtmlFunction){
    this.container = container;
    this.container_padding=10; 
    this.topology = topology;
    this.nodeInnerHtmlFunction = nodeInnerHtmlFunction||this.defaultNodeInnerHtml;
    this.svgLine = new SvgLine({
      targetElement:container,
      lines:[],
      lineStyle:0,
      lineOrientation:1,
      hasBeginArrows:false,
      hasEndArrows:false,
      // hasEndArrows:true,
      lineColor:"#6482B9",
      lineGradientColor:"#EC3832",
      lineWidth:2
    });
  }

  render(){
    // 渲染节点
    this.renderNode();
    // 渲染连线
    this.renderLine();
  }

  /**
   * 渲染所有节点
   */
  renderNode(){
    this.container.querySelectorAll(".node").forEach(elemetn=>elemetn.remove());

    // const container_x=this.container.offsetLeft||0;
    // const container_y=this.container.offsetTop||0;
    const padding=this.container_padding;

    // 渲染所有节点
    this.topology.nodes.forEach(node=>{
      const nodeElement = document.createElement('div');
      nodeElement.className = 'node';
      nodeElement.id = `${node.id}`;
      // nodeElement.style.left = `${node.x+container_x}px`;
      // nodeElement.style.top = `${node.y+container_y}px`;
      nodeElement.style.left = `${node.x+padding}px`;
      nodeElement.style.top = `${node.y+padding}px`;

      // 根据节点类型设置样式
      if (!node.parentId) {
        nodeElement.style.background = 'linear-gradient(135deg, #9b59b6, #8e44ad)';
      } else if (node.children.length > 0) {
        nodeElement.style.background = 'linear-gradient(135deg, #2ecc71, #27ae60)';
      } else {
        nodeElement.style.background = 'linear-gradient(135deg, #e74c3c, #c0392b)';
      }
      // 如果节点被选中，添加边框
      if (this.topology.selectedNode === node.id) {
        nodeElement.style.boxShadow = '0 0 0 3px #f1c40f';
      }
      nodeElement.innerHTML=this.nodeInnerHtmlFunction(node);
      this.container.appendChild(nodeElement);
      // 添加拖拽事件
      this.makeDraggable(nodeElement, node);
      node.nodeElement=nodeElement;
    });
  }
  /**
   * 计算并渲染连线
   */
  renderLine(){
    // 清理连线
    this.svgLine.lines.length=0;
    this.svgLine.render();
    this.topology.connections.forEach(conn=>{
      const formNode = conn.from;
      const toNode = conn.to;
      const line={
        startXY:[],
        endXY:[],
        lineWidth: 2,
      }
      if(conn.type=="parent"||conn.type=="parent_prev"){
        line.startXY[0]=formNode.nodeElement.offsetLeft+formNode.nodeElement.clientWidth/2;
        line.startXY[1] = formNode.nodeElement.offsetTop+formNode.nodeElement.clientHeight;
        line.endXY[0]=toNode.nodeElement.offsetLeft+toNode.nodeElement.clientWidth/2;
        line.endXY[1] = toNode.nodeElement.offsetTop;
        line.orientation=1;
        if(conn.type=="parent"){
          line.lineStyle=0;
          line.lineWidth=2;
        }else{
          line.lineStyle=1;
          line.lineWidth=1;
        }
      }else{        
        line.startXY[0]=formNode.nodeElement.offsetLeft+formNode.nodeElement.clientWidth;
        line.startXY[1] = formNode.nodeElement.offsetTop+formNode.nodeElement.clientHeight/2;
        line.endXY[0]=toNode.nodeElement.offsetLeft;
        line.endXY[1] = toNode.nodeElement.offsetTop+formNode.nodeElement.clientHeight/2;
        line.orientation=0;
        line.lineStyle=3;
        line.lineWidth=2;
      }
      this.svgLine.lines.push(line);
    });
    this.svgLine.render();
  }

  arrangeLayout(){
    this.topology.arrangeLayout();
    this.render();
  }

  /**
   * 绑定拖拽事件
   * @param {*} nodeElement 节点元素
   * @param {*} node 节点
   */
  makeDraggable(nodeElement,node){
    let isDragging = false;
    let offsetX, offsetY;
    const containerRect = this.container.getBoundingClientRect();
    const container_x=containerRect.left||0;
    const container_y=containerRect.top||0;
    nodeElement.addEventListener('mousedown',(e)=>{
      isDragging = true;
      this.topology.selectNode(node.id);
      this.render();

      // 计算偏移量
      const rect = document.getElementById(nodeElement.id).getBoundingClientRect();
      offsetX = e.clientX - rect.left;
      offsetY = e.clientY - rect.top;
      
      e.preventDefault();
    });

    document.addEventListener("mousemove",(e)=>{
      if (!isDragging) return;
      
      // 计算新位置
      // 鼠标坐标-父级元素坐标-偏移量+父级元素滚动条距离
      const x = e.clientX - container_x - offsetX+this.container.scrollLeft;
      const y = e.clientY - container_y - offsetY+this.container.scrollTop;
      // const x = e.clientX-container_x;
      // const y = e.clientY-container_y;
      
      // 更新节点位置
      this.topology.moveNode(node.id, x, y);
      this.render();
    });

    document.addEventListener('mouseup', () => {
      isDragging = false;
    });
  }

  defaultNodeInnerHtml(node) {
    return `
        <div class="node-id">${node.id}</div>
        <div class="node-info">层级: ${node.level}</div>
        ${node.parentId ? `<div class="node-info">父节点: ${node.parentId}</div>` : ''}
        ${node.prevId ? `<div class="node-info">前节点: ${node.prevId}</div>` : ''}
        ${node.nextId ? `<div class="node-info">后节点: ${node.nextId}</div>` : ''}
      `;
  }
}